package com.app.demo.controller;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import com.app.core.mvc.result.Result;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Retryable;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author qiangt
 * @version 1.0
 * @description: 测试限流
 * @date 2023/10/14 8:11
 */
@RestController
@RequestMapping("/test")
@RequiredArgsConstructor
@Slf4j
public class TestController {

    private final StringRedisTemplate redisTemplate;

    private final String KEY = "retry";

    // multiplier，乘积因子
    // @Retryable(value = {Exception.class}, maxAttempts = 3, backoff = @Backoff(delay = 1000))
    @Retryable(value = {Exception.class}, maxAttempts = 4, backoff = @Backoff(delay = 1000, multiplier = 2))
    @GetMapping("retry")
    public Result<String> retry() {
        String value = redisTemplate.opsForValue().get(KEY);
        if (StrUtil.isNotBlank(value)) {
            redisTemplate.opsForValue().increment(KEY);
        } else {
            redisTemplate.opsForValue().set(KEY, "1");
        }
        String s = redisTemplate.opsForValue().get(KEY);
        log.info("retry count: {}, time: {}", s, System.currentTimeMillis());
        if (Convert.toInt(s) < 5) {
            throw new RuntimeException("test retry failed");
        }
        return Result.success(s);
    }
}
